/* 
 * File:   Socket.cpp
 * Author: jacek
 * 
 * Created on 14 kwiecień 2011, 18:11
 */

#include "include/Socket.h"
namespace Net {
Socket::Socket() {

	listner = false;
	binded = false;
	connected = false;
	descryptor = -1;
}
Socket::Socket(const Socket& src){
	listner = src.listner;
	binded = src.binded;
	connected = src.connected;
	descryptor = src.descryptor;
}
Socket::~Socket() {
}
void Socket::Connect(char* ip, int port) {
	sockaddr_in address = CreateSockAddrIn(ip, port);
	if (connect(descryptor, (sockaddr*) &address, NetAddress::size) == -1)
		throw SocketException(errno);
}
void Socket::Connect(NetAddress& address) {

	if (connect(descryptor, address.GetSockAddr(), NetAddress::size) == -1)
		throw SocketException(errno);
}

sockaddr_in Socket::CreateSockAddrIn(char* ip, int port) {
	sockaddr_in address;
	memset(&address, '\0', sizeof(address));
	address.sin_family = AF_INET;
	address.sin_addr.s_addr = inet_addr(ip);
	address.sin_port = htonl(port);
	return address;
}
void Socket::CreateUDPRecevSocket(NetAddress& address) {
	descryptor = socket(AF_INET, UDP, 0);
	if (descryptor <= 0)
		throw SocketException(strerror(errno));

	if (bind(descryptor, address.GetSockAddr(), address.size) == -1)
		throw SocketException(errno);
	this->binded=true;

}
void Socket::CreateTCPRecevSocket(NetAddress& address, int qlen) {
	descryptor = socket(AF_INET, TCP, 0);
	if (descryptor <= 0)
		throw SocketException(strerror(errno));

	if (bind(descryptor, address.GetSockAddr(), address.size) == -1)
		throw SocketException(errno);
	this->binded=true;

	if (listen(descryptor, qlen) == -1)
		throw SocketException(errno);
	this->listner=true;

}
void Socket::CreateSendingSocket(Protocol protocol) {

	descryptor = socket(AF_INET, protocol, 0);
	if (descryptor <= 0)
		throw SocketException(strerror(errno));
}
void Socket::Close() {
	if (close(descryptor) == -1)
		throw SocketException(errno);
}
void Socket::Send(Package& package) {
	if (send(descryptor, package.buffor, package.size, 0) == -1)
		throw SocketException(errno);
}
void Socket::SendTo(Package& package, NetAddress& hostAddress) {
	if (sendto(descryptor, package.buffor, package.size, 0,
			hostAddress.GetSockAddr(), NetAddress::size) == -1)
		throw SocketException(errno);
}
void Socket::Recev(Package* package) {

	int recvBytes = 0;
	recvBytes = recv(descryptor, package->buffor, package->size, 0);
	if (recvBytes < 0) {
		throw SocketException(errno);
	}
}
void Socket::RecevFrom(Package* package,NetAddress* peerAddress) {
	socklen_t size = NetAddress::size;
	int recvBytes = 0;
	recvBytes = recvfrom(descryptor, package->buffor, package->size, 0,
			peerAddress->GetSockAddr(), &size);
	if (recvBytes < 0) {
		throw SocketException(errno);
	}
}

Socket Socket::AcceptNewConnetion(Socket* listingSocket,
		NetAddress * peerAddress) {
	if (!listingSocket->listner)
		throw SocketException("Socket is not listing socket!!");
	socklen_t size = peerAddress->size;
	Socket sock;
	sock.descryptor = accept(listingSocket->descryptor,
			peerAddress->GetSockAddr(), &size);
	sock.connected = true;
	return sock;
}
}

